"""
策略基类模块

定义策略的基础接口和通用功能。

作者: AI Assistant
版本: 1.0.0
日期: 2025-01-06
"""

from abc import ABC, abstractmethod
import pandas as pd
from typing import Optional


class StrategyBase(ABC):
    """
    策略基类
    
    所有回测策略都应该继承这个基类，并实现必要的方法。
    
    属性:
        name: 策略名称
        min_period: 策略需要的最小数据周期
        params: 策略参数字典
        
    子类必须实现:
        generate_signal(): 生成交易信号
        
    示例:
        >>> class MyStrategy(StrategyBase):
        ...     def __init__(self):
        ...         super().__init__(name="我的策略", min_period=20)
        ...     
        ...     def generate_signal(self, data, current_bar):
        ...         # 实现信号生成逻辑
        ...         if condition:
        ...             return 'BUY'
        ...         return 'HOLD'
    """
    
    def __init__(self, name: str = "基础策略", min_period: int = 1, **kwargs):
        """
        初始化策略
        
        参数:
            name: 策略名称
            min_period: 策略需要的最小数据周期（如MA20策略至少需要20天数据）
            **kwargs: 其他策略参数
        """
        self.name = name
        self.min_period = min_period
        self.params = kwargs
        self.data = None  # 将在initialize时设置
    
    def initialize(self, data: pd.DataFrame):
        """
        初始化策略
        
        在回测开始前调用，可以在这里预处理数据或初始化指标。
        
        参数:
            data: 完整的历史数据
        """
        self.data = data
    
    @abstractmethod
    def generate_signal(self, data: pd.DataFrame, current_bar: pd.Series) -> str:
        """
        生成交易信号（必须由子类实现）
        
        参数:
            data: 当前及之前的所有数据
            current_bar: 当前K线数据
            
        返回:
            str: 交易信号，可选值：
                - 'BUY': 买入信号
                - 'SELL': 卖出信号
                - 'HOLD': 持有/观望
        """
        pass
    
    def get_params(self) -> dict:
        """
        获取策略参数
        
        返回:
            dict: 策略参数字典
        """
        return {
            'name': self.name,
            'min_period': self.min_period,
            **self.params
        }
    
    def set_params(self, **kwargs):
        """
        设置策略参数
        
        参数:
            **kwargs: 要设置的参数
        """
        self.params.update(kwargs)
    
    def __str__(self):
        """字符串表示"""
        return f"{self.name} (min_period={self.min_period})"
    
    def __repr__(self):
        """详细表示"""
        return f"<{self.__class__.__name__}: {self.name}>"

